﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Globalization;
using XmlStudio.Utilities;

namespace XmlStudio.Validators {
    /// <summary>
    /// Options when validating some XML part.
    /// </summary>
    public enum XmlValidationOptions {
        /// <summary>
        /// Element name.
        /// </summary>
        Element,
        /// <summary>
        /// Prefix.
        /// </summary>
        Prefix,
        /// <summary>
        /// Namespace uri.
        /// </summary>
        NamespaceUri,
        /// <summary>
        /// Attribute name.
        /// </summary>
        AttributeName,
        /// <summary>
        /// Attribute value.
        /// </summary>
        AttributeValue
    }

    /// <summary>
    /// Validation rule for XML validation.
    /// </summary>
    public class XmlValidationRule : ValidationRule {
        #region Fields
        private string errorMessage;
        private XmlValidationOptions validationOptions;
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="XmlValidationRule"/> class.
        /// </summary>
        public XmlValidationRule() { }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the error message to be used when validation fails.
        /// </summary>
        public string ErrorMessage {
            get { return this.errorMessage; }
            set { this.errorMessage = value; }
        }

        /// <summary>
        /// Gets or sets the validation options.
        /// </summary>
        /// <value>The validation options.</value>
        public XmlValidationOptions ValidationOptions {
            get { return this.validationOptions; }
            set { this.validationOptions = value; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Validates the 'value' argument using the regular 
        /// expression and RegexOptions associated with this object.
        /// </summary>
        public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
            ValidationResult result = ValidationResult.ValidResult;

            string text = value as string ?? String.Empty;
            string error = string.Empty;
            switch(this.validationOptions) {
                case XmlValidationOptions.AttributeName:
                    error = XmlChecker.CheckAttributeName(text);
                    break;
                case XmlValidationOptions.AttributeValue:
                    error = XmlChecker.CheckAttributeValue(text);
                    break;
                case XmlValidationOptions.Element:
                    error = XmlChecker.CheckElementName(text);
                    break;
                case XmlValidationOptions.NamespaceUri:
                    error = XmlChecker.CheckElementNamespaceUri(text);
                    break;
                case XmlValidationOptions.Prefix:
                    error = XmlChecker.CheckElementPrefix(text);
                    break;
            }

            if(!string.IsNullOrEmpty(error)) {
                this.ErrorMessage = error;
                result = new ValidationResult(false, this.ErrorMessage);
            }

            return result;
        }
        #endregion
    }
}